package org.test4j.mock.processor.filer;

import com.squareup.javapoet.ClassName;
import g_asm.org.objectweb.asm.Type;

import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class ClassNames {
    public static final String MockUp_Suffix = "MockUp";

    public static final String Mock_Package_Prefix = "mock";

    public static final String Mock_Package_WithDot = Mock_Package_Prefix + ".";

    public static final ClassName CN_Bean = ClassName.get("org.springframework.context.annotation", "Bean");

    public static final ClassName CN_Configuration = ClassName.get("org.springframework.context.annotation", "Configuration");

    public static final ClassName CN_Collection = ClassName.get(Collection.class);

    private static Map<String, ClassName> primitives = new HashMap<>(16);

    static {
        primitives.put("void", ClassName.get(Void.class));
        primitives.put("boolean", ClassName.get(Boolean.class));
        primitives.put("char", ClassName.get(Character.class));
        primitives.put("byte", ClassName.get(Byte.class));
        primitives.put("short", ClassName.get(Short.class));
        primitives.put("int", ClassName.get(Integer.class));
        primitives.put("float", ClassName.get(Float.class));
        primitives.put("long", ClassName.get(Long.class));
        primitives.put("double", ClassName.get(Double.class));
    }

    private ClassNames() {
    }

    public static ClassName getClassName(String fullName) {
        if (primitives.containsKey(fullName)) {
            return primitives.get(fullName);
        }
        int index = fullName.lastIndexOf('.');
        String packName = index < 0 ? "" : fullName.substring(0, index);
        String className = index < 0 ? fullName : fullName.substring(index + 1);
        return ClassName.get(packName, className);
    }

    public static ClassName getClassName(Type type) {
        String name = type.getClassName();
        if (primitives.containsKey(name)) {
            return primitives.get(name);
        }
        try {
            Class clazz = Class.forName(name);
            int access = clazz.getModifiers();
            if (Modifier.isPublic(access)) {
                return ClassName.get(clazz);
            }
        } catch (Throwable e) {
        }
        return ClassName.get(Object.class);
    }
}